package com.bytedance.common.plugin.framework;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences.Editor;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import com.bytedance.common.plugin.baseface.BasePlugin;
import com.bytedance.common.plugin.baseface.BaseProxy;
import com.bytedance.common.plugin.framework.model.InstallPluginItem;
import com.bytedance.common.plugin.framework.model.Plugin;
import com.bytedance.common.plugin.framework.model.Plugin.PluginInfo;
import com.bytedance.common.plugin.framework.model.ProcessType;
import com.bytedance.common.plugin.framework.model.ResourceType;
import com.bytedance.common.plugin.framework.util.PluginUtil;
import com.bytedance.common.utility.Logger;
import com.bytedance.common.utility.reflect.Reflect;

import org.json.JSONArray;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import inline.PluginExtractor;
import inline.PluginLoader;

public class PluginManager {
    public static Context sContext;
    public Resources mResources;
    public AssetManager mAssetManager;
    public Resources d;
    public AssetManager e;
    public static final Map<String, Plugin> sPluginMap = new ConcurrentHashMap<>();
    private static PluginManager sPluginManager;


    private PluginManager(Context context) throws Exception {
        if ((context instanceof ContextWrapper)) {
            PluginManager.sContext = ((ContextWrapper) context).getBaseContext();
            this.mResources = PluginManager.sContext.getResources();
            this.mAssetManager = this.mResources.getAssets();
            this.d = this.mResources;
            this.e = this.mAssetManager;
            PluginManager.loadProxyPluginFace();
            PluginManager.loadInstalledPlugin();
        } else {
            throw new IllegalArgumentException("PluginManager init fail for context is null");
        }
    }

    public static PluginManager getPluginManager() {
        if (PluginManager.sPluginManager == null) {
            throw new IllegalArgumentException("PluginManager is not init");
        }
        return PluginManager.sPluginManager;
    }

    public static Plugin getPlugin(String pluginPackageName) {
        return PluginManager.sPluginMap.get(pluginPackageName);
    }

    public static Plugin createPlugin(String packageName, String pluginPath) throws Exception {
        if (!TextUtils.isEmpty(packageName) && PluginManager.sContext != null && !TextUtils.isEmpty(pluginPath)) {
            if (Logger.debug()) {
                Logger.d("Plugin", "PluginManager createPlugin start");
            }

            try {
                String pluginDir = PluginManager.pluginDir();
                if (TextUtils.isEmpty(pluginDir)) {
                    return null;
                }

                String outputApkPath = pluginDir + "/" + packageName + "/apk";
                String outputDexPath = pluginDir + "/" + packageName + "/dex";
                String outputLibPath = pluginDir + "/" + packageName + "/lib";
                PackageInfo packageInfo = PluginUtil.getPkgInfo(PluginManager.sContext, pluginPath);
                if (packageInfo == null) {
                    PluginManager.deletePluginFile(packageName);
                    return null;
                }

                ApplicationInfo applicationInfo = PluginUtil.getApplicationInfo(PluginManager.sContext, pluginPath, new PackageInfo[]{packageInfo});
                if (applicationInfo == null) {
                    PluginManager.deletePluginFile(packageName);
                    return null;
                }

                Signature[] pluginSignatures = packageInfo.signatures;
                Signature[] hostSignatures = PluginManager.sContext.getPackageManager().getPackageInfo(PluginManager.sContext.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
                if ((packageName.equals(applicationInfo.packageName))
                        && PluginUtil.signEquals(PluginManager.sContext, pluginSignatures, hostSignatures)) {
                    return new Plugin(packageName, outputApkPath, outputDexPath, outputLibPath, packageInfo, applicationInfo);
                }

                if (Logger.debug()) {
                    Logger.e("Plugin", "PluginManager vertify error");
                }
                PluginManager.deletePluginFile(packageName);
            } catch (Exception e) {
                Logger.e("Plugin", "CreatePlugin failed", e);
                throw e;
            }
        }
        return null;
    }

    public static Boolean checkPlugin(InstallPluginItem pluginItem) {
        if (pluginItem == null || PluginManager.sPluginMap.size() <= 0) {
            return Boolean.FALSE;
        } else if (PluginUtil.getProcessType(PluginManager.sContext) != ProcessType.MAIN) {
            return Boolean.FALSE;
        } else {
            try {
                Plugin plugin = PluginManager.sPluginMap.get(pluginItem.packageName);
                if (plugin != null) {
                    PluginInfo pluginInfo = Plugin.mPluginInfoMap.get(plugin.packageName);
                    if (pluginInfo == null) {
                        return Boolean.FALSE;
                    } else if (!pluginInfo.proxyClass.equals(pluginItem.proxyClass)) {
                        return Boolean.FALSE;
                    } else if (!pluginInfo.pluginClass.equals(pluginItem.pluginClass)) {
                        return Boolean.FALSE;
                    } else if (pluginInfo.resourceType != pluginItem.resourceType) {
                        return Boolean.FALSE;
                    } else if (pluginInfo.processType == pluginItem.processType) {
                        int apkVersionCode = pluginItem.apkVersionCode.intValue();
                        String apkMd5 = pluginItem.apkMD5;
                        boolean result;
                        if (plugin.mPackageInfo == null || apkVersionCode < 0 || TextUtils.isEmpty(apkMd5)) {
                            result = false;
                        } else if (apkVersionCode != plugin.mPackageInfo.versionCode) {
                            result = false;
                        } else {
                            result = apkMd5.equals(PluginUtil.fileToMD5(new File(plugin.apkPath + "/" + plugin.fileName())));
                        }

                        if (!result) {
                            return Boolean.FALSE;
                        }

                        if (Logger.debug()) {
                            Logger.d("Plugin", "plugin faceItem.checked = " + pluginInfo.installResult);
                        }

                        if (pluginInfo.installResult.booleanValue()) {
                            return Boolean.FALSE;
                        }

                        if (Logger.debug()) {
                            Logger.d("Plugin", "remove package = " + pluginItem.packageName + " for checkFalse");
                        }
                        PluginManager.sPluginMap.remove(pluginItem.packageName);
                        return Boolean.TRUE;
                    } else {
                        return Boolean.FALSE;
                    }
                } else {
                    return Boolean.FALSE;
                }
            } catch (Throwable throwable) {
                Logger.e("Plugin", "CheckPlugin failed.", throwable);
            }
            return Boolean.FALSE;
        }
    }

    public static void ensurePluginManagerInstance(Context context) throws Exception {
        if (sPluginManager == null) {
            synchronized (PluginManager.class) {
                if (sPluginManager == null) {
                    sPluginManager = new PluginManager(context);
                }
            }
        }
    }

    public static ClassLoader getHostClassLoader() {
        return PluginManager.sContext == null ? null : PluginManager.sContext.getClassLoader();
    }

    public static void deletePluginFile(String name) {
        File file = new File(PluginManager.pluginDir() + "/" + name);
        if (file.exists()) {
            PluginUtil.deleteFile(file);
        }
    }

    public static List<Plugin> getPlugins() {
        return new ArrayList(PluginManager.sPluginMap.values());
    }

    public final void startInstalledPlugin() throws Exception {
        if (PluginManager.sPluginMap.size() > 0) {
            if (Logger.debug()) {
                Logger.d("Plugin", "PluginManager startInstalledPlugin start");
            }

            ArrayList<Pair<List<File>, File>> pluginDexAndLibList = new ArrayList();
            Iterator<Entry<String, Plugin>> iterator = PluginManager.sPluginMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, Plugin> entry = iterator.next();
                if (entry.getValue() == null) {
                    continue;
                }
                Plugin plugin = entry.getValue();
                if (!plugin.isPluginInstalled(new Object[0])) {
                    continue;
                }

                Context context = PluginManager.sContext;
                Pair<List<File>, File> pair = null;
                if (context != null && plugin.isPluginInstalled(new Object[0])) {
                    if (Logger.debug()) {
                        Logger.d("Plugin", "Plugin startPlugin start");
                    }
                    pair = PluginExtractor.extractDexAndLib(context, plugin.mApplicationInfo, new File(plugin.dexPath), new File(plugin.libPath));
                }
                if (pair != null) {
                    pluginDexAndLibList.add(pair);
                }
            }

            Context context = PluginManager.sContext;
            File pluginOptDir = new File(PluginManager.pluginDir() + "/opt");
            if (!pluginOptDir.exists()) {
                pluginOptDir.mkdirs();
            }

            PluginLoader.install(context, pluginDexAndLibList, pluginOptDir);
            Iterator<Entry<String, Plugin>> it = PluginManager.sPluginMap.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, Plugin> entry = it.next();
                if (entry.getValue() == null) {
                    continue;
                }

                Plugin plugin = entry.getValue();
                if (!plugin.isPluginInstalled(new Object[0])) {
                    continue;
                }

                PluginInfo pluginInfo = Plugin.mPluginInfoMap.get(plugin.packageName);
                if (pluginInfo == null) {
                    continue;
                }

                try {
                    if (Logger.debug()) {
                        Logger.d("Plugin", "Plugin initPlugin start");
                    }
                    Class proxyClass = Reflect.forName(pluginInfo.proxyClass);
                    plugin.mBaseProxy = (BaseProxy) Reflect.onClass(proxyClass).call("inst").target;
                    Class pluginClass = Reflect.forName(pluginInfo.pluginClass);
                    plugin.mBaseProxy.setPlugin((BasePlugin) Reflect.onClass(pluginClass).create().target);
                    continue;
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
            PluginManager.checkInstallResult();
            this.loadInstalledPluginRes();
        }
    }

    public static String pluginDir() {
        return PluginManager.sContext == null ? null : PluginManager.sContext.getFilesDir().getAbsolutePath() + "/ss_plugins";
    }

    public static void saveProxyPluginFace() throws Exception {
        if (Logger.debug()) {
            Logger.d("Plugin", "saveProxyPluginFace start");
        }

        Editor editor = PluginUtil.getPluginPreferences(PluginManager.sContext).edit();
        try {
            JSONArray jsonArray = new JSONArray();
            Iterator<Entry<String, PluginInfo>> iterator = Plugin.mPluginInfoMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, PluginInfo> entry = iterator.next();
                if (entry == null) {
                    continue;
                }
                StringBuilder stringBuilder = new StringBuilder(entry.getKey());
                stringBuilder.append("|").append(entry.getValue().proxyClass)
                        .append("|").append(entry.getValue().pluginClass)
                        .append("|").append(entry.getValue().resourceType.getTypeValue())
                        .append("|").append(entry.getValue().processType.getTypeValue())
                        .append("|");
                String suffix = android.support.design.a.isTextEmpty(entry.getValue().processNameSuffix) ? "" : entry.getValue().processNameSuffix;
                stringBuilder.append(suffix)
                        .append("|").append(entry.getValue().installResult)
                        .append("|").append(PluginUtil.toJsonArray(entry.getValue().processNameSuffixList)
                        .toString());
                String str = stringBuilder.toString();
                if (TextUtils.isEmpty(str)) {
                    continue;
                }

                jsonArray.put(str);
            }

            if (jsonArray.length() > 0) {
                editor.putString("proxy_plugin_face", jsonArray.toString());
                PluginUtil.apply(editor);
            }
        } catch (Exception e) {
            Logger.e("Plugin", "saveProxyPluginFace failed", e);
        }

        return;
    }

    private static void loadInstalledPlugin() throws Exception {
        if (Logger.debug()) {
            Logger.d("Plugin", "PluginManager loadInstalledPlugin start");
        }
        String pluginDir = PluginManager.pluginDir();
        if (!TextUtils.isEmpty(pluginDir)) {
            File pluginDirFile = new File(pluginDir);
            if ((pluginDirFile.exists()) && (pluginDirFile.isDirectory())) {
                File[] pluginFiles = pluginDirFile.listFiles();
                int length = pluginFiles.length;
                for (int i = 0; i < length; ++i) {
                    File pluginFile = pluginFiles[i];
                    if (pluginFile.isDirectory()) {
                        String pluginFileName = pluginFile.getName();
                        File pluginApk = new File(pluginDir + "/" + pluginFileName + "/apk", pluginFileName + ".apk");
                        String pluginFilePath = null;
                        if (pluginApk.exists()) {
                            pluginFilePath = pluginApk.getAbsolutePath();
                        }
                        Plugin plugin = PluginManager.createPlugin(pluginFileName, pluginFilePath);
                        if (plugin == null) {
                            continue;
                        }
                        if (!Plugin.isTargetProcess(PluginManager.sContext, plugin.packageName)) {
                            continue;
                        }
                        PluginManager.sPluginMap.put(pluginFileName, plugin);
                    }
                }
            }
        }
    }

    private static void checkInstallResult() throws Exception {
        if (PluginManager.sPluginMap.size() > 0) {
            Iterator<Entry<String, Plugin>> iterator = PluginManager.sPluginMap.entrySet().iterator();
            if (PluginUtil.getProcessType(PluginManager.sContext) == ProcessType.MAIN) {
                boolean changed = false;
                while (iterator.hasNext()) {
                    Entry<String, Plugin> entry = iterator.next();
                    if (entry == null) {
                        continue;
                    }

                    Plugin plugin = entry.getValue();
                    if (plugin == null) {
                        continue;
                    }

                    if (plugin.mBaseProxy == null) {
                        continue;
                    }

                    if (plugin.mBaseProxy.check(plugin.packageName)) {
                        if (Logger.debug()) {
                            Logger.d("Plugin", "plugin check = true");
                        }
                    } else {
                        if (Logger.debug()) {
                            Logger.d("Plugin", "plugin check = false");
                        }
                        Plugin.setInstallResult(plugin.packageName, Boolean.FALSE);
                        iterator.remove();
                        changed = true;
                    }
                }

                if (changed) {
                    PluginManager.saveProxyPluginFace();
                }
            }
        }
    }

    private void loadInstalledPluginRes() throws Exception {
        Resources v1_1;
        Object v0_1;
        if (PluginManager.sPluginMap.size() > 0 && this.mAssetManager != null && this.mResources != null) {
            if (Logger.debug()) {
                Logger.d("Plugin", "PluginManager loadInstalledPluginRes start");
            }

            try {
                LinkedHashSet v3 = new LinkedHashSet();
                PluginUtil.mergeRes(this.mAssetManager, ((Set) v3));
                Iterator v4 = PluginManager.sPluginMap.entrySet().iterator();
                int v1 = 0;
                while (v4.hasNext()) {
                    v0_1 = v4.next();
                    if (((Entry) v0_1).getValue() == null) {
                        continue;
                    }

                    v0_1 = ((Entry) v0_1).getValue();
                    if (!((Plugin) v0_1).isPluginInstalled(new Object[0])) {
                        continue;
                    }

                    String v5 = ((Plugin) v0_1).apkPath + "/" + ((Plugin) v0_1).packageName + ".apk";
                    if (Logger.debug()) {
                        Logger.d("Plugin", "apkPath = " + v5);
                    }

                    if (((Plugin) v0_1).a(PluginManager.sContext)) {
                        ((Set) v3).add(v5);
                        v1 = 1;
                        continue;
                    }

                    ((Plugin) v0_1).mResources = PluginUtil.makeNewResource(this.mResources, new String[]{v5});
                }

                Resources v2 = this.mResources;
                if (v1 != 0) {
                    v2 = PluginUtil.makeNewResource(this.mResources, (String[]) v3.toArray(new String[v3.size()]));
                }

                Iterator v3_1 = PluginManager.sPluginMap.entrySet().iterator();
                while (v3_1.hasNext()) {
                    v0_1 = v3_1.next();
                    if (((Entry) v0_1).getValue() == null) {
                        continue;
                    }

                    v0_1 = ((Entry) v0_1).getValue();
                    if (!((Plugin) v0_1).a(PluginManager.sContext)) {
                        v1_1 = ((Plugin) v0_1).mResources;
                    } else {
                        ((Plugin) v0_1).mResources = v2;
                        v1_1 = v2;
                    }

                    if (((Plugin) v0_1).mBaseProxy == null) {
                        continue;
                    }

                    if (Logger.debug()) {
                        Logger.d("Plugin", "set plugin res = " + v1_1.toString());
                    }

                    ((Plugin) v0_1).mBaseProxy.setPluginRes(v1_1, ((Plugin) v0_1).packageName);
                    ((Plugin) v0_1).mBaseProxy.setHostResMap(com.bytedance.common.plugin.a.c, ((Plugin) v0_1).packageName);
                }

                if (Logger.debug()) {
                    Logger.d("Plugin", "loaded res = " + v2.toString() + " replace res = " + this.mResources.toString());
                }

                this.mResources = v2;
                this.mAssetManager = this.mResources.getAssets();
            } catch (Exception v0) {
                Logger.e("Plugin", "LoadInstalledPluginRes failed", ((Throwable) v0));
                throw v0;
            }
        }
    }

    private static void loadProxyPluginFace() throws Exception {
        ProcessType v4;
        int v15 = 7;
        int v14 = 6;
        if (Logger.debug()) {
            Logger.d("Plugin", "loadProxyPluginFace start");
        }

        String proxyPluginFace = PluginUtil.getPluginPreferences(PluginManager.sContext)
                .getString("proxy_plugin_face", "");
        if (!TextUtils.isEmpty(proxyPluginFace)) {
            try {
                JSONArray ja = new JSONArray(proxyPluginFace);
                int length = ja.length();
                for (int i = 0; i < length; ++i) {
                    String pairString = ja.getString(i);
                    if (!TextUtils.isEmpty(pairString)) {
                        if (Logger.debug()) {
                            Logger.d("Plugin", "pairString = " + pairString);
                        }

                        String[] v2 = pairString.split("\\|");
                        if (v2 == null) {
                            continue;
                        }

                        if (v2.length < v14) {
                            continue;
                        }

                        ResourceType resourceType = Integer.parseInt(v2[3]) == ResourceType.PLUGIN.getTypeValue()
                                ? ResourceType.PLUGIN
                                : ResourceType.APP;
                        int v0_2 = Integer.parseInt(v2[4]);
                        if (v0_2 == ProcessType.OTHER.getTypeValue()) {
                            v4 = ProcessType.OTHER;
                        } else if (v0_2 == ProcessType.MAIN.getTypeValue()) {
                            v4 = ProcessType.MAIN;
                        } else if (v0_2 == ProcessType.WORK.getTypeValue()) {
                            v4 = ProcessType.WORK;
                        } else {
                            v4 = ProcessType.OTHER;
                        }

                        String v5 = v2[5];
                        Boolean v7 = Boolean.TRUE;
                        if (v2.length > v14) {
                            v7 = Boolean.valueOf(Boolean.parseBoolean(v2[6]));
                        }

                        List v6 = null;
                        if (v2.length > v15) {
                            try {
                                v6 = PluginUtil.toList(new JSONArray(v2[7]));
                            } catch (Throwable v0_3) {
                                Logger.e("Plugin", "PluginUtil.toList failed", v0_3);
                            }
                        }

                        Plugin.mPluginInfoMap.put(v2[0], new PluginInfo(v2[1], v2[2], resourceType, v4, v5, v6, v7));
                    }
                }
            } catch (Exception e) {
                Logger.e("Plugin", "LoadProxyPluginFace failed", e);
                throw e;
            }
        }
    }
}

